{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7063dc62",
   "metadata": {},
   "source": [
    "# 快速成为深度学习全栈工程师第11课书面作业\n",
    "\n",
    "学号：114499\n",
    "\n",
    "**作业内容：**  \n",
    "请使用不同的神经网络训练MNIST，给出关键代码和loss曲线图\n",
    "\n",
    "提示：https://pytorch.org/docs/stable/torchvision/models.html#classification，\n",
    "可以尝试使用预训练模型（只需要讲pretrained=True就行，但可能由于网络太大下载过慢或失败）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c6362c22",
   "metadata": {},
   "source": [
    "采用预训练模型vgg11来训练MNIST，这里有几个要点：  \n",
    "1. vgg最小输入的尺寸是32 * 32，MNIST图片为28 * 28，因此需要在transform中先将图片resize到32 * 32  \n",
    "2. vgg是处理3通过的彩色图片，而MNIST是单通道的灰度图片，因此需要在输入层将预置模型改为单通道的  \n",
    "3. vgg的输出是1000个分类，而MNIST只需要10个分类，因此需要将vgg模型最后的全连接层替换一下，最终收敛输出10个分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "90935452",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torchvision\n",
    "import torch\n",
    "import matplotlib.pyplot as plt\n",
    "import torchvision.models as models\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torch.optim as optim"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e3b9383a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cuda:0\n"
     ]
    }
   ],
   "source": [
    "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
    "print(device)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "2fb1e84a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<torch._C.Generator at 0x20e8993f090>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n_epochs = 3\n",
    "batch_size_train = 64\n",
    "batch_size_test = 1000\n",
    "learning_rate = 0.01\n",
    "momentum = 0.5\n",
    "log_interval = 10\n",
    "random_seed = 1\n",
    "torch.backends.cudnn.enabled = False\n",
    "torch.manual_seed(random_seed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a6ff8d6e",
   "metadata": {},
   "outputs": [],
   "source": [
    "transform = torchvision.transforms.Compose([\n",
    "                                torchvision.transforms.Resize(32), #需要将图片扩大到32*32\n",
    "                               torchvision.transforms.ToTensor(),\n",
    "                               torchvision.transforms.Normalize(\n",
    "                                 (0.1307,), (0.3081,))\n",
    "                             ])\n",
    "train_dataset = torchvision.datasets.MNIST('.', train=True, transform=transform,\n",
    "                                          download=True)\n",
    "test_dataset = torchvision.datasets.MNIST('.', train=False, transform=transform,\n",
    "                                         download=True)\n",
    "train_loader = torch.utils.data.DataLoader(train_dataset, \n",
    "                                               batch_size=batch_size_train,\n",
    "                                               shuffle=True, \n",
    "                                               num_workers=2,\n",
    "                                               pin_memory=True,\n",
    "                                               drop_last=True\n",
    "                                           \n",
    "                                            )\n",
    "test_loader = torch.utils.data.DataLoader(test_dataset, \n",
    "                                               batch_size=16,\n",
    "                                               shuffle=False, \n",
    "                                               num_workers=2,\n",
    "                                               pin_memory=True,\n",
    "                                               drop_last=False\n",
    "                                            )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "121ab92b",
   "metadata": {},
   "outputs": [],
   "source": [
    "examples = enumerate(test_loader)\n",
    "batch_idx, (example_data, example_targets) = next(examples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "bb76597d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure()\n",
    "for i in range(6):\n",
    "    plt.subplot(2,3,i+1)\n",
    "    plt.tight_layout()\n",
    "    plt.imshow(example_data[i][0], cmap='gray', interpolation='none')\n",
    "    plt.title(\"Ground Truth: {}\".format(example_targets[i]))\n",
    "    plt.xticks([])\n",
    "    plt.yticks([])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "b935ca7f",
   "metadata": {},
   "outputs": [],
   "source": [
    "vgg = models.vgg16(pretrained=True)\n",
    "#更改vgg网络的input为单通道\n",
    "vgg.features[0]=nn.Conv2d(1, 64, kernel_size=3, padding=1)\n",
    "\n",
    "# 构建新的全连接层，从原来的1000个分类收敛到10个分类\n",
    "vgg.classifier = torch.nn.Sequential(torch.nn.Linear(25088, 100),\n",
    "                                       torch.nn.ReLU(),\n",
    "                                       torch.nn.Dropout(p=0.5),\n",
    "                                       torch.nn.Linear(100, 10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "f36fafde",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "VGG(\n",
       "  (features): Sequential(\n",
       "    (0): Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (1): ReLU(inplace=True)\n",
       "    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (3): ReLU(inplace=True)\n",
       "    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "    (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (6): ReLU(inplace=True)\n",
       "    (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (8): ReLU(inplace=True)\n",
       "    (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "    (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (11): ReLU(inplace=True)\n",
       "    (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (13): ReLU(inplace=True)\n",
       "    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (15): ReLU(inplace=True)\n",
       "    (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "    (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (18): ReLU(inplace=True)\n",
       "    (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (20): ReLU(inplace=True)\n",
       "    (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (22): ReLU(inplace=True)\n",
       "    (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "    (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (25): ReLU(inplace=True)\n",
       "    (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (27): ReLU(inplace=True)\n",
       "    (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
       "    (29): ReLU(inplace=True)\n",
       "    (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "  )\n",
       "  (avgpool): AdaptiveAvgPool2d(output_size=(7, 7))\n",
       "  (classifier): Sequential(\n",
       "    (0): Linear(in_features=25088, out_features=100, bias=True)\n",
       "    (1): ReLU()\n",
       "    (2): Dropout(p=0.5, inplace=False)\n",
       "    (3): Linear(in_features=100, out_features=10, bias=True)\n",
       "  )\n",
       ")"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vgg.to(device)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "aa87114b",
   "metadata": {},
   "outputs": [],
   "source": [
    "optimizer = optim.SGD(vgg.parameters(), lr=learning_rate, momentum=momentum)\n",
    "loss_func = nn.CrossEntropyLoss()\n",
    "test_loss_func = nn.CrossEntropyLoss(reduction='sum')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "fb6b892b",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_losses = []\n",
    "train_counter = []\n",
    "test_losses = []\n",
    "test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)]\n",
    "def train(epoch):\n",
    "    vgg.train()\n",
    "    for batch_idx, (data, target) in enumerate(train_loader):\n",
    "        optimizer.zero_grad()\n",
    "        output = vgg(data.to(device))\n",
    "        loss = loss_func(output, target.to(device))\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        \n",
    "        if batch_idx % log_interval == 0:\n",
    "            print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(\n",
    "                epoch, batch_idx * len(data), len(train_loader.dataset),\n",
    "                100. * batch_idx / len(train_loader), loss.item()))\n",
    "            train_losses.append(loss.item())\n",
    "            train_counter.append((batch_idx*64) + ((epoch-1)*len(train_loader.dataset)))\n",
    "            torch.save(vgg.state_dict(), 'MNIST/model.pth')\n",
    "            torch.save(optimizer.state_dict(), 'MNIST/optimizer.pth')\n",
    "def test():\n",
    "    vgg.eval()\n",
    "    test_loss = 0\n",
    "    correct = 0\n",
    "    with torch.no_grad():\n",
    "        for data, target in test_loader:\n",
    "            output = vgg(data.to(device))\n",
    "            test_loss += test_loss_func(output, target.to(device)).cpu().item()\n",
    "            pred = output.cpu().data.max(1, keepdim=True)[1]\n",
    "            correct += pred.eq(target.data.view_as(pred)).sum()\n",
    "    test_loss /= len(test_loader.dataset)\n",
    "    test_losses.append(test_loss)\n",
    "    print('\\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n",
    "        test_loss, correct, len(test_loader.dataset),100. * correct / len(test_loader.dataset)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "2ddddfa2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Test set: Avg. loss: 2.2912, Accuracy: 976/10000 (10%)\n",
      "\n",
      "Train Epoch: 1 [0/60000 (0%)]\tLoss: 2.280855\n",
      "Train Epoch: 1 [640/60000 (1%)]\tLoss: 3.763898\n",
      "Train Epoch: 1 [1280/60000 (2%)]\tLoss: 1.900400\n",
      "Train Epoch: 1 [1920/60000 (3%)]\tLoss: 1.881342\n",
      "Train Epoch: 1 [2560/60000 (4%)]\tLoss: 1.527088\n",
      "Train Epoch: 1 [3200/60000 (5%)]\tLoss: 1.019314\n",
      "Train Epoch: 1 [3840/60000 (6%)]\tLoss: 1.056890\n",
      "Train Epoch: 1 [4480/60000 (7%)]\tLoss: 1.458303\n",
      "Train Epoch: 1 [5120/60000 (9%)]\tLoss: 0.516135\n",
      "Train Epoch: 1 [5760/60000 (10%)]\tLoss: 0.558510\n",
      "Train Epoch: 1 [6400/60000 (11%)]\tLoss: 0.432661\n",
      "Train Epoch: 1 [7040/60000 (12%)]\tLoss: 0.201451\n",
      "Train Epoch: 1 [7680/60000 (13%)]\tLoss: 0.208955\n",
      "Train Epoch: 1 [8320/60000 (14%)]\tLoss: 0.388246\n",
      "Train Epoch: 1 [8960/60000 (15%)]\tLoss: 0.109290\n",
      "Train Epoch: 1 [9600/60000 (16%)]\tLoss: 0.086373\n",
      "Train Epoch: 1 [10240/60000 (17%)]\tLoss: 0.265805\n",
      "Train Epoch: 1 [10880/60000 (18%)]\tLoss: 0.096704\n",
      "Train Epoch: 1 [11520/60000 (19%)]\tLoss: 0.053353\n",
      "Train Epoch: 1 [12160/60000 (20%)]\tLoss: 0.053551\n",
      "Train Epoch: 1 [12800/60000 (21%)]\tLoss: 0.053747\n",
      "Train Epoch: 1 [13440/60000 (22%)]\tLoss: 0.029126\n",
      "Train Epoch: 1 [14080/60000 (23%)]\tLoss: 0.108272\n",
      "Train Epoch: 1 [14720/60000 (25%)]\tLoss: 0.176089\n",
      "Train Epoch: 1 [15360/60000 (26%)]\tLoss: 0.281082\n",
      "Train Epoch: 1 [16000/60000 (27%)]\tLoss: 0.231466\n",
      "Train Epoch: 1 [16640/60000 (28%)]\tLoss: 0.027654\n",
      "Train Epoch: 1 [17280/60000 (29%)]\tLoss: 0.213988\n",
      "Train Epoch: 1 [17920/60000 (30%)]\tLoss: 0.070232\n",
      "Train Epoch: 1 [18560/60000 (31%)]\tLoss: 0.229194\n",
      "Train Epoch: 1 [19200/60000 (32%)]\tLoss: 0.018796\n",
      "Train Epoch: 1 [19840/60000 (33%)]\tLoss: 0.166888\n",
      "Train Epoch: 1 [20480/60000 (34%)]\tLoss: 0.045918\n",
      "Train Epoch: 1 [21120/60000 (35%)]\tLoss: 0.461921\n",
      "Train Epoch: 1 [21760/60000 (36%)]\tLoss: 0.221038\n",
      "Train Epoch: 1 [22400/60000 (37%)]\tLoss: 0.391125\n",
      "Train Epoch: 1 [23040/60000 (38%)]\tLoss: 0.106398\n",
      "Train Epoch: 1 [23680/60000 (39%)]\tLoss: 0.182768\n",
      "Train Epoch: 1 [24320/60000 (41%)]\tLoss: 0.039055\n",
      "Train Epoch: 1 [24960/60000 (42%)]\tLoss: 0.137154\n",
      "Train Epoch: 1 [25600/60000 (43%)]\tLoss: 0.037882\n",
      "Train Epoch: 1 [26240/60000 (44%)]\tLoss: 0.032417\n",
      "Train Epoch: 1 [26880/60000 (45%)]\tLoss: 0.121751\n",
      "Train Epoch: 1 [27520/60000 (46%)]\tLoss: 0.011293\n",
      "Train Epoch: 1 [28160/60000 (47%)]\tLoss: 0.104436\n",
      "Train Epoch: 1 [28800/60000 (48%)]\tLoss: 0.085422\n",
      "Train Epoch: 1 [29440/60000 (49%)]\tLoss: 0.173108\n",
      "Train Epoch: 1 [30080/60000 (50%)]\tLoss: 0.008840\n",
      "Train Epoch: 1 [30720/60000 (51%)]\tLoss: 0.057910\n",
      "Train Epoch: 1 [31360/60000 (52%)]\tLoss: 0.022325\n",
      "Train Epoch: 1 [32000/60000 (53%)]\tLoss: 0.014532\n",
      "Train Epoch: 1 [32640/60000 (54%)]\tLoss: 0.185639\n",
      "Train Epoch: 1 [33280/60000 (55%)]\tLoss: 0.124713\n",
      "Train Epoch: 1 [33920/60000 (57%)]\tLoss: 0.020617\n",
      "Train Epoch: 1 [34560/60000 (58%)]\tLoss: 0.083683\n",
      "Train Epoch: 1 [35200/60000 (59%)]\tLoss: 0.034696\n",
      "Train Epoch: 1 [35840/60000 (60%)]\tLoss: 0.072807\n",
      "Train Epoch: 1 [36480/60000 (61%)]\tLoss: 0.077011\n",
      "Train Epoch: 1 [37120/60000 (62%)]\tLoss: 0.006309\n",
      "Train Epoch: 1 [37760/60000 (63%)]\tLoss: 0.219175\n",
      "Train Epoch: 1 [38400/60000 (64%)]\tLoss: 0.033253\n",
      "Train Epoch: 1 [39040/60000 (65%)]\tLoss: 0.023153\n",
      "Train Epoch: 1 [39680/60000 (66%)]\tLoss: 0.009447\n",
      "Train Epoch: 1 [40320/60000 (67%)]\tLoss: 0.114939\n",
      "Train Epoch: 1 [40960/60000 (68%)]\tLoss: 0.015046\n",
      "Train Epoch: 1 [41600/60000 (69%)]\tLoss: 0.047478\n",
      "Train Epoch: 1 [42240/60000 (70%)]\tLoss: 0.133005\n",
      "Train Epoch: 1 [42880/60000 (72%)]\tLoss: 0.012340\n",
      "Train Epoch: 1 [43520/60000 (73%)]\tLoss: 0.022752\n",
      "Train Epoch: 1 [44160/60000 (74%)]\tLoss: 0.005667\n",
      "Train Epoch: 1 [44800/60000 (75%)]\tLoss: 0.161914\n",
      "Train Epoch: 1 [45440/60000 (76%)]\tLoss: 0.005705\n",
      "Train Epoch: 1 [46080/60000 (77%)]\tLoss: 0.248806\n",
      "Train Epoch: 1 [46720/60000 (78%)]\tLoss: 0.039627\n",
      "Train Epoch: 1 [47360/60000 (79%)]\tLoss: 0.029351\n",
      "Train Epoch: 1 [48000/60000 (80%)]\tLoss: 0.018697\n",
      "Train Epoch: 1 [48640/60000 (81%)]\tLoss: 0.049536\n",
      "Train Epoch: 1 [49280/60000 (82%)]\tLoss: 0.091026\n",
      "Train Epoch: 1 [49920/60000 (83%)]\tLoss: 0.027319\n",
      "Train Epoch: 1 [50560/60000 (84%)]\tLoss: 0.008374\n",
      "Train Epoch: 1 [51200/60000 (85%)]\tLoss: 0.006208\n",
      "Train Epoch: 1 [51840/60000 (86%)]\tLoss: 0.231546\n",
      "Train Epoch: 1 [52480/60000 (88%)]\tLoss: 0.018671\n",
      "Train Epoch: 1 [53120/60000 (89%)]\tLoss: 0.110693\n",
      "Train Epoch: 1 [53760/60000 (90%)]\tLoss: 0.003818\n",
      "Train Epoch: 1 [54400/60000 (91%)]\tLoss: 0.005235\n",
      "Train Epoch: 1 [55040/60000 (92%)]\tLoss: 0.006497\n",
      "Train Epoch: 1 [55680/60000 (93%)]\tLoss: 0.039589\n",
      "Train Epoch: 1 [56320/60000 (94%)]\tLoss: 0.014553\n",
      "Train Epoch: 1 [56960/60000 (95%)]\tLoss: 0.070491\n",
      "Train Epoch: 1 [57600/60000 (96%)]\tLoss: 0.244382\n",
      "Train Epoch: 1 [58240/60000 (97%)]\tLoss: 0.056578\n",
      "Train Epoch: 1 [58880/60000 (98%)]\tLoss: 0.172627\n",
      "Train Epoch: 1 [59520/60000 (99%)]\tLoss: 0.016381\n",
      "\n",
      "Test set: Avg. loss: 0.0641, Accuracy: 9808/10000 (98%)\n",
      "\n",
      "Train Epoch: 2 [0/60000 (0%)]\tLoss: 0.007564\n",
      "Train Epoch: 2 [640/60000 (1%)]\tLoss: 0.005526\n",
      "Train Epoch: 2 [1280/60000 (2%)]\tLoss: 0.007198\n",
      "Train Epoch: 2 [1920/60000 (3%)]\tLoss: 0.003763\n",
      "Train Epoch: 2 [2560/60000 (4%)]\tLoss: 0.001846\n",
      "Train Epoch: 2 [3200/60000 (5%)]\tLoss: 0.043288\n",
      "Train Epoch: 2 [3840/60000 (6%)]\tLoss: 0.016574\n",
      "Train Epoch: 2 [4480/60000 (7%)]\tLoss: 0.004937\n",
      "Train Epoch: 2 [5120/60000 (9%)]\tLoss: 0.024964\n",
      "Train Epoch: 2 [5760/60000 (10%)]\tLoss: 0.042304\n",
      "Train Epoch: 2 [6400/60000 (11%)]\tLoss: 0.004561\n",
      "Train Epoch: 2 [7040/60000 (12%)]\tLoss: 0.005890\n",
      "Train Epoch: 2 [7680/60000 (13%)]\tLoss: 0.085384\n",
      "Train Epoch: 2 [8320/60000 (14%)]\tLoss: 0.049198\n",
      "Train Epoch: 2 [8960/60000 (15%)]\tLoss: 0.048416\n",
      "Train Epoch: 2 [9600/60000 (16%)]\tLoss: 0.079544\n",
      "Train Epoch: 2 [10240/60000 (17%)]\tLoss: 0.022113\n",
      "Train Epoch: 2 [10880/60000 (18%)]\tLoss: 0.060360\n",
      "Train Epoch: 2 [11520/60000 (19%)]\tLoss: 0.015460\n",
      "Train Epoch: 2 [12160/60000 (20%)]\tLoss: 0.028459\n",
      "Train Epoch: 2 [12800/60000 (21%)]\tLoss: 0.009591\n",
      "Train Epoch: 2 [13440/60000 (22%)]\tLoss: 0.048568\n",
      "Train Epoch: 2 [14080/60000 (23%)]\tLoss: 0.002595\n",
      "Train Epoch: 2 [14720/60000 (25%)]\tLoss: 0.007838\n",
      "Train Epoch: 2 [15360/60000 (26%)]\tLoss: 0.080030\n",
      "Train Epoch: 2 [16000/60000 (27%)]\tLoss: 0.002945\n",
      "Train Epoch: 2 [16640/60000 (28%)]\tLoss: 0.005821\n",
      "Train Epoch: 2 [17280/60000 (29%)]\tLoss: 0.005492\n",
      "Train Epoch: 2 [17920/60000 (30%)]\tLoss: 0.003218\n",
      "Train Epoch: 2 [18560/60000 (31%)]\tLoss: 0.004221\n",
      "Train Epoch: 2 [19200/60000 (32%)]\tLoss: 0.016906\n",
      "Train Epoch: 2 [19840/60000 (33%)]\tLoss: 0.004884\n",
      "Train Epoch: 2 [20480/60000 (34%)]\tLoss: 0.145837\n",
      "Train Epoch: 2 [21120/60000 (35%)]\tLoss: 0.004890\n",
      "Train Epoch: 2 [21760/60000 (36%)]\tLoss: 0.029060\n",
      "Train Epoch: 2 [22400/60000 (37%)]\tLoss: 0.046238\n",
      "Train Epoch: 2 [23040/60000 (38%)]\tLoss: 0.038882\n",
      "Train Epoch: 2 [23680/60000 (39%)]\tLoss: 0.009246\n",
      "Train Epoch: 2 [24320/60000 (41%)]\tLoss: 0.004086\n",
      "Train Epoch: 2 [24960/60000 (42%)]\tLoss: 0.001198\n",
      "Train Epoch: 2 [25600/60000 (43%)]\tLoss: 0.027412\n",
      "Train Epoch: 2 [26240/60000 (44%)]\tLoss: 0.008227\n",
      "Train Epoch: 2 [26880/60000 (45%)]\tLoss: 0.027256\n",
      "Train Epoch: 2 [27520/60000 (46%)]\tLoss: 0.016821\n",
      "Train Epoch: 2 [28160/60000 (47%)]\tLoss: 0.056116\n",
      "Train Epoch: 2 [28800/60000 (48%)]\tLoss: 0.165684\n",
      "Train Epoch: 2 [29440/60000 (49%)]\tLoss: 0.043146\n",
      "Train Epoch: 2 [30080/60000 (50%)]\tLoss: 0.136214\n",
      "Train Epoch: 2 [30720/60000 (51%)]\tLoss: 0.105844\n",
      "Train Epoch: 2 [31360/60000 (52%)]\tLoss: 0.003170\n",
      "Train Epoch: 2 [32000/60000 (53%)]\tLoss: 0.074401\n",
      "Train Epoch: 2 [32640/60000 (54%)]\tLoss: 0.018352\n",
      "Train Epoch: 2 [33280/60000 (55%)]\tLoss: 0.047256\n",
      "Train Epoch: 2 [33920/60000 (57%)]\tLoss: 0.033486\n",
      "Train Epoch: 2 [34560/60000 (58%)]\tLoss: 0.094589\n",
      "Train Epoch: 2 [35200/60000 (59%)]\tLoss: 0.002309\n",
      "Train Epoch: 2 [35840/60000 (60%)]\tLoss: 0.095546\n",
      "Train Epoch: 2 [36480/60000 (61%)]\tLoss: 0.003627\n",
      "Train Epoch: 2 [37120/60000 (62%)]\tLoss: 0.017827\n",
      "Train Epoch: 2 [37760/60000 (63%)]\tLoss: 0.020359\n",
      "Train Epoch: 2 [38400/60000 (64%)]\tLoss: 0.019330\n",
      "Train Epoch: 2 [39040/60000 (65%)]\tLoss: 0.004890\n",
      "Train Epoch: 2 [39680/60000 (66%)]\tLoss: 0.001448\n",
      "Train Epoch: 2 [40320/60000 (67%)]\tLoss: 0.049651\n",
      "Train Epoch: 2 [40960/60000 (68%)]\tLoss: 0.009274\n",
      "Train Epoch: 2 [41600/60000 (69%)]\tLoss: 0.147397\n",
      "Train Epoch: 2 [42240/60000 (70%)]\tLoss: 0.010233\n",
      "Train Epoch: 2 [42880/60000 (72%)]\tLoss: 0.049801\n",
      "Train Epoch: 2 [43520/60000 (73%)]\tLoss: 0.002224\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Epoch: 2 [44160/60000 (74%)]\tLoss: 0.067279\n",
      "Train Epoch: 2 [44800/60000 (75%)]\tLoss: 0.010196\n",
      "Train Epoch: 2 [45440/60000 (76%)]\tLoss: 0.033586\n",
      "Train Epoch: 2 [46080/60000 (77%)]\tLoss: 0.013316\n",
      "Train Epoch: 2 [46720/60000 (78%)]\tLoss: 0.088307\n",
      "Train Epoch: 2 [47360/60000 (79%)]\tLoss: 0.055377\n",
      "Train Epoch: 2 [48000/60000 (80%)]\tLoss: 0.007728\n",
      "Train Epoch: 2 [48640/60000 (81%)]\tLoss: 0.004238\n",
      "Train Epoch: 2 [49280/60000 (82%)]\tLoss: 0.130527\n",
      "Train Epoch: 2 [49920/60000 (83%)]\tLoss: 0.012923\n",
      "Train Epoch: 2 [50560/60000 (84%)]\tLoss: 0.010031\n",
      "Train Epoch: 2 [51200/60000 (85%)]\tLoss: 0.046592\n",
      "Train Epoch: 2 [51840/60000 (86%)]\tLoss: 0.088851\n",
      "Train Epoch: 2 [52480/60000 (88%)]\tLoss: 0.013361\n",
      "Train Epoch: 2 [53120/60000 (89%)]\tLoss: 0.008216\n",
      "Train Epoch: 2 [53760/60000 (90%)]\tLoss: 0.011350\n",
      "Train Epoch: 2 [54400/60000 (91%)]\tLoss: 0.005316\n",
      "Train Epoch: 2 [55040/60000 (92%)]\tLoss: 0.055095\n",
      "Train Epoch: 2 [55680/60000 (93%)]\tLoss: 0.119281\n",
      "Train Epoch: 2 [56320/60000 (94%)]\tLoss: 0.051793\n",
      "Train Epoch: 2 [56960/60000 (95%)]\tLoss: 0.156001\n",
      "Train Epoch: 2 [57600/60000 (96%)]\tLoss: 0.006020\n",
      "Train Epoch: 2 [58240/60000 (97%)]\tLoss: 0.005510\n",
      "Train Epoch: 2 [58880/60000 (98%)]\tLoss: 0.016889\n",
      "Train Epoch: 2 [59520/60000 (99%)]\tLoss: 0.001972\n",
      "\n",
      "Test set: Avg. loss: 0.0278, Accuracy: 9915/10000 (99%)\n",
      "\n",
      "Train Epoch: 3 [0/60000 (0%)]\tLoss: 0.139956\n",
      "Train Epoch: 3 [640/60000 (1%)]\tLoss: 0.004491\n",
      "Train Epoch: 3 [1280/60000 (2%)]\tLoss: 0.019359\n",
      "Train Epoch: 3 [1920/60000 (3%)]\tLoss: 0.020225\n",
      "Train Epoch: 3 [2560/60000 (4%)]\tLoss: 0.060790\n",
      "Train Epoch: 3 [3200/60000 (5%)]\tLoss: 0.002391\n",
      "Train Epoch: 3 [3840/60000 (6%)]\tLoss: 0.008122\n",
      "Train Epoch: 3 [4480/60000 (7%)]\tLoss: 0.016158\n",
      "Train Epoch: 3 [5120/60000 (9%)]\tLoss: 0.021449\n",
      "Train Epoch: 3 [5760/60000 (10%)]\tLoss: 0.009320\n",
      "Train Epoch: 3 [6400/60000 (11%)]\tLoss: 0.145912\n",
      "Train Epoch: 3 [7040/60000 (12%)]\tLoss: 0.013451\n",
      "Train Epoch: 3 [7680/60000 (13%)]\tLoss: 0.014594\n",
      "Train Epoch: 3 [8320/60000 (14%)]\tLoss: 0.002354\n",
      "Train Epoch: 3 [8960/60000 (15%)]\tLoss: 0.010617\n",
      "Train Epoch: 3 [9600/60000 (16%)]\tLoss: 0.014554\n",
      "Train Epoch: 3 [10240/60000 (17%)]\tLoss: 0.000873\n",
      "Train Epoch: 3 [10880/60000 (18%)]\tLoss: 0.013587\n",
      "Train Epoch: 3 [11520/60000 (19%)]\tLoss: 0.012083\n",
      "Train Epoch: 3 [12160/60000 (20%)]\tLoss: 0.017432\n",
      "Train Epoch: 3 [12800/60000 (21%)]\tLoss: 0.005804\n",
      "Train Epoch: 3 [13440/60000 (22%)]\tLoss: 0.026079\n",
      "Train Epoch: 3 [14080/60000 (23%)]\tLoss: 0.002882\n",
      "Train Epoch: 3 [14720/60000 (25%)]\tLoss: 0.054855\n",
      "Train Epoch: 3 [15360/60000 (26%)]\tLoss: 0.066343\n",
      "Train Epoch: 3 [16000/60000 (27%)]\tLoss: 0.076526\n",
      "Train Epoch: 3 [16640/60000 (28%)]\tLoss: 0.001335\n",
      "Train Epoch: 3 [17280/60000 (29%)]\tLoss: 0.094595\n",
      "Train Epoch: 3 [17920/60000 (30%)]\tLoss: 0.030746\n",
      "Train Epoch: 3 [18560/60000 (31%)]\tLoss: 0.008292\n",
      "Train Epoch: 3 [19200/60000 (32%)]\tLoss: 0.002903\n",
      "Train Epoch: 3 [19840/60000 (33%)]\tLoss: 0.021926\n",
      "Train Epoch: 3 [20480/60000 (34%)]\tLoss: 0.017374\n",
      "Train Epoch: 3 [21120/60000 (35%)]\tLoss: 0.005332\n",
      "Train Epoch: 3 [21760/60000 (36%)]\tLoss: 0.001543\n",
      "Train Epoch: 3 [22400/60000 (37%)]\tLoss: 0.023671\n",
      "Train Epoch: 3 [23040/60000 (38%)]\tLoss: 0.034357\n",
      "Train Epoch: 3 [23680/60000 (39%)]\tLoss: 0.003004\n",
      "Train Epoch: 3 [24320/60000 (41%)]\tLoss: 0.021838\n",
      "Train Epoch: 3 [24960/60000 (42%)]\tLoss: 0.003153\n",
      "Train Epoch: 3 [25600/60000 (43%)]\tLoss: 0.001774\n",
      "Train Epoch: 3 [26240/60000 (44%)]\tLoss: 0.001679\n",
      "Train Epoch: 3 [26880/60000 (45%)]\tLoss: 0.040042\n",
      "Train Epoch: 3 [27520/60000 (46%)]\tLoss: 0.003157\n",
      "Train Epoch: 3 [28160/60000 (47%)]\tLoss: 0.097365\n",
      "Train Epoch: 3 [28800/60000 (48%)]\tLoss: 0.041316\n",
      "Train Epoch: 3 [29440/60000 (49%)]\tLoss: 0.004913\n",
      "Train Epoch: 3 [30080/60000 (50%)]\tLoss: 0.001724\n",
      "Train Epoch: 3 [30720/60000 (51%)]\tLoss: 0.000981\n",
      "Train Epoch: 3 [31360/60000 (52%)]\tLoss: 0.001181\n",
      "Train Epoch: 3 [32000/60000 (53%)]\tLoss: 0.012431\n",
      "Train Epoch: 3 [32640/60000 (54%)]\tLoss: 0.044068\n",
      "Train Epoch: 3 [33280/60000 (55%)]\tLoss: 0.004440\n",
      "Train Epoch: 3 [33920/60000 (57%)]\tLoss: 0.001425\n",
      "Train Epoch: 3 [34560/60000 (58%)]\tLoss: 0.026053\n",
      "Train Epoch: 3 [35200/60000 (59%)]\tLoss: 0.022466\n",
      "Train Epoch: 3 [35840/60000 (60%)]\tLoss: 0.000672\n",
      "Train Epoch: 3 [36480/60000 (61%)]\tLoss: 0.119526\n",
      "Train Epoch: 3 [37120/60000 (62%)]\tLoss: 0.041158\n",
      "Train Epoch: 3 [37760/60000 (63%)]\tLoss: 0.002480\n",
      "Train Epoch: 3 [38400/60000 (64%)]\tLoss: 0.000536\n",
      "Train Epoch: 3 [39040/60000 (65%)]\tLoss: 0.004371\n",
      "Train Epoch: 3 [39680/60000 (66%)]\tLoss: 0.001229\n",
      "Train Epoch: 3 [40320/60000 (67%)]\tLoss: 0.004606\n",
      "Train Epoch: 3 [40960/60000 (68%)]\tLoss: 0.015736\n",
      "Train Epoch: 3 [41600/60000 (69%)]\tLoss: 0.088617\n",
      "Train Epoch: 3 [42240/60000 (70%)]\tLoss: 0.025610\n",
      "Train Epoch: 3 [42880/60000 (72%)]\tLoss: 0.004190\n",
      "Train Epoch: 3 [43520/60000 (73%)]\tLoss: 0.001741\n",
      "Train Epoch: 3 [44160/60000 (74%)]\tLoss: 0.005600\n",
      "Train Epoch: 3 [44800/60000 (75%)]\tLoss: 0.001936\n",
      "Train Epoch: 3 [45440/60000 (76%)]\tLoss: 0.007571\n",
      "Train Epoch: 3 [46080/60000 (77%)]\tLoss: 0.032548\n",
      "Train Epoch: 3 [46720/60000 (78%)]\tLoss: 0.009386\n",
      "Train Epoch: 3 [47360/60000 (79%)]\tLoss: 0.001442\n",
      "Train Epoch: 3 [48000/60000 (80%)]\tLoss: 0.005031\n",
      "Train Epoch: 3 [48640/60000 (81%)]\tLoss: 0.021246\n",
      "Train Epoch: 3 [49280/60000 (82%)]\tLoss: 0.000226\n",
      "Train Epoch: 3 [49920/60000 (83%)]\tLoss: 0.043549\n",
      "Train Epoch: 3 [50560/60000 (84%)]\tLoss: 0.015384\n",
      "Train Epoch: 3 [51200/60000 (85%)]\tLoss: 0.023167\n",
      "Train Epoch: 3 [51840/60000 (86%)]\tLoss: 0.148354\n",
      "Train Epoch: 3 [52480/60000 (88%)]\tLoss: 0.004417\n",
      "Train Epoch: 3 [53120/60000 (89%)]\tLoss: 0.050302\n",
      "Train Epoch: 3 [53760/60000 (90%)]\tLoss: 0.011214\n",
      "Train Epoch: 3 [54400/60000 (91%)]\tLoss: 0.001516\n",
      "Train Epoch: 3 [55040/60000 (92%)]\tLoss: 0.008385\n",
      "Train Epoch: 3 [55680/60000 (93%)]\tLoss: 0.016069\n",
      "Train Epoch: 3 [56320/60000 (94%)]\tLoss: 0.035491\n",
      "Train Epoch: 3 [56960/60000 (95%)]\tLoss: 0.003998\n",
      "Train Epoch: 3 [57600/60000 (96%)]\tLoss: 0.004079\n",
      "Train Epoch: 3 [58240/60000 (97%)]\tLoss: 0.002796\n",
      "Train Epoch: 3 [58880/60000 (98%)]\tLoss: 0.002281\n",
      "Train Epoch: 3 [59520/60000 (99%)]\tLoss: 0.009012\n",
      "\n",
      "Test set: Avg. loss: 0.0254, Accuracy: 9920/10000 (99%)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "test()\n",
    "for epoch in range(1, n_epochs + 1):\n",
    "    train(epoch)\n",
    "    test()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "696612f8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'negative log likelihood loss')"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure()\n",
    "plt.plot(train_counter, train_losses, color='blue')\n",
    "plt.scatter(test_counter, test_losses, color='red')\n",
    "plt.legend(['Train Loss', 'Test Loss'], loc='upper right')\n",
    "plt.xlabel('number of training examples seen')\n",
    "plt.ylabel('negative log likelihood loss')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "e1a48cc3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "with torch.no_grad():\n",
    "    output = vgg(example_data.to(device))\n",
    "fig = plt.figure()\n",
    "for i in range(6):\n",
    "    plt.subplot(2,3,i+1)\n",
    "    plt.tight_layout()\n",
    "    plt.imshow(example_data[i][0], cmap='gray', interpolation='none')\n",
    "    plt.title(\"Prediction: {}\".format(\n",
    "    output.data.max(1, keepdim=True)[1][i].item()))\n",
    "    plt.xticks([])\n",
    "    plt.yticks([])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c01fe186",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:pytorch]",
   "language": "python",
   "name": "conda-env-pytorch-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
